package org.minuframework.utils;

import java.io.File;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import org.minuframework.file.PropertiesFile;

/**
 * 本工具类参考开源项目JFinal中的PropKit所写
 * @author 米mi
 */
public class PropUtils {
    
    private static PropertiesFile                                  propertiesFile;
    private static final ConcurrentHashMap<String, PropertiesFile> CONCURRENT_HASH_MAP = new ConcurrentHashMap<String, PropertiesFile>();
    
    public static PropertiesFile use(String fileName) {
        PropertiesFile result = CONCURRENT_HASH_MAP.get(fileName);
        if (result == null) {
            synchronized (PropUtils.class) {
                result = CONCURRENT_HASH_MAP.get(fileName);
                if (result == null) {
                    result = new PropertiesFile(fileName);
                    CONCURRENT_HASH_MAP.put(fileName, result);
                    if (PropUtils.propertiesFile == null) {
                        PropUtils.propertiesFile = result;
                    }
                }
            }
        }
        return propertiesFile;
    }
    
    public static PropertiesFile use(String fileName, String encoding) {
        PropertiesFile result = CONCURRENT_HASH_MAP.get(fileName);
        if (result == null) {
            synchronized (PropUtils.class) {
                result = CONCURRENT_HASH_MAP.get(fileName);
                if (result == null) {
                    result = new PropertiesFile(fileName, encoding);
                    CONCURRENT_HASH_MAP.put(fileName, result);
                    if (PropUtils.propertiesFile == null) {
                        PropUtils.propertiesFile = result;
                    }
                }
            }
        }
        return propertiesFile;
    }
    
    public static PropertiesFile useless(String fileName) {
        if (CONCURRENT_HASH_MAP.contains(fileName)) {
            PropertiesFile result = CONCURRENT_HASH_MAP.remove(fileName);
            if (PropUtils.propertiesFile == result) {
                PropUtils.propertiesFile = null;
            }
            return result;
        }
        return null;
    }
    
    public static PropertiesFile use(File file) {
        PropertiesFile result = CONCURRENT_HASH_MAP.get(file.getName());
        if (result == null) {
            synchronized (PropUtils.class) {
                result = CONCURRENT_HASH_MAP.get(file.getName());
                if (result == null) {
                    result = new PropertiesFile(file);
                    CONCURRENT_HASH_MAP.put(file.getName(), result);
                    if (PropUtils.propertiesFile == null) {
                        PropUtils.propertiesFile = result;
                    }
                }
            }
        }
        return propertiesFile;
    }
    
    public static PropertiesFile use(File file, String encoding) {
        PropertiesFile result = CONCURRENT_HASH_MAP.get(file.getName());
        if (result == null) {
            synchronized (PropUtils.class) {
                result = CONCURRENT_HASH_MAP.get(file.getName());
                if (result == null) {
                    result = new PropertiesFile(file, encoding);
                    CONCURRENT_HASH_MAP.put(file.getName(), result);
                    if (PropUtils.propertiesFile == null) {
                        PropUtils.propertiesFile = result;
                    }
                }
            }
        }
        return propertiesFile;
    }
    
    public static PropertiesFile useless(File file) {
        if (CONCURRENT_HASH_MAP.contains(file.getName())) {
            PropertiesFile result = CONCURRENT_HASH_MAP.remove(file.getName());
            if (PropUtils.propertiesFile == result) {
                PropUtils.propertiesFile = null;
            }
            return result;
        }
        return null;
    }
    
    public static void clear() {
        PropUtils.propertiesFile = null;
        CONCURRENT_HASH_MAP.clear();
    }
    
    public static PropertiesFile append(PropertiesFile propertiesFile) {
        synchronized (PropUtils.class) {
            if (PropUtils.propertiesFile == null) {
                PropUtils.propertiesFile = propertiesFile;
            } else {
                PropUtils.propertiesFile.append(propertiesFile);
            }
            return PropUtils.propertiesFile;
        }
    }
    
    public static PropertiesFile append(Properties properties) {
        return append(new PropertiesFile(properties));
    }
    
    public static PropertiesFile append(String fileName) {
        return append(new PropertiesFile(fileName));
    }
    
    public static PropertiesFile append(String fileName, String encoding) {
        return append(new PropertiesFile(fileName, encoding));
    }
    
    public static PropertiesFile append(File file) {
        return append(new PropertiesFile(file));
    }
    
    public static PropertiesFile append(File file, String encoding) {
        return append(new PropertiesFile(file, encoding));
    }
    
    public static PropertiesFile setProperty(String key, String value) {
        return getPropertiesFile().setProperty(key, value);
    }
    
    public static PropertiesFile getPropertiesFile() {
        return propertiesFile;
    }
    
    public static PropertiesFile getPropertiesFile(String key) {
        if (CONCURRENT_HASH_MAP.containsKey(key)) { return CONCURRENT_HASH_MAP.get(key); }
        return null;
    }
    
    public static Object get(Object key) {
        return getPropertiesFile().get(key);
    }
    
    public static Object get(String prefix, Object key) {
        return getPropertiesFile().get(getKey(prefix, key));
    }
    
    public static Object get(String key) {
        return getPropertiesFile().get(key);
    }
    
    public static Object get(String prefix, String key) {
        return getPropertiesFile().get(getKey(prefix, key));
    }
    
    public static String getProperty(String key) {
        return getPropertiesFile().getProperty(key);
    }
    
    public static String getProperty(String prefix, String key) {
        return getPropertiesFile().getProperty(getKey(prefix, key));
    }
    
    public static int getInt(String key) {
        return getPropertiesFile().getInt(key);
    }
    
    public static int getInt(String prefix, String key) {
        return getPropertiesFile().getInt(getKey(prefix, key));
    }
    
    public static long getLong(String key) {
        return getPropertiesFile().getLong(key);
    }
    
    public static long getLong(String prefix, String key) {
        return getPropertiesFile().getLong(getKey(prefix, key));
    }
    
    public static double getDouble(String key) {
        return getPropertiesFile().getDouble(key);
    }
    
    public static double getDouble(String prefix, String key) {
        return getPropertiesFile().getDouble(getKey(prefix, key));
    }
    
    public static float getFloat(String key) {
        return getPropertiesFile().getFloat(key);
    }
    
    public static float getFloat(String prefix, String key) {
        return getPropertiesFile().getFloat(getKey(prefix, key));
    }
    
    public static boolean getBoolean(String key) {
        return getPropertiesFile().getBoolean(key);
    }
    
    public static boolean getBoolean(String prefix, String key) {
        return getPropertiesFile().getBoolean(getKey(prefix, key));
    }
    
    public static boolean containsKey(Object key) {
        return getPropertiesFile().containsKey(key);
    }
    
    public static boolean containsKey(String prefix, Object key) {
        return getPropertiesFile().containsKey(getKey(prefix, key));
    }
    
    public static boolean containsKey(String key) {
        return getPropertiesFile().containsKey(key);
    }
    
    public static boolean containsKey(String prefix, String key) {
        return getPropertiesFile().containsKey(getKey(prefix, key));
    }
    
    public static Properties getProperties() {
        return getPropertiesFile().getProperties();
    }
    
    public static String getKey(String prefix, Object key) {
        StringBuilder result = new StringBuilder();
        result.append(prefix);
        result.append(".");
        result.append(key);
        return result.toString();
    }
    
    public static String getKey(String prefix, String key) {
        StringBuilder result = new StringBuilder();
        result.append(prefix);
        result.append(".");
        result.append(key);
        return result.toString();
    }
    
}
